//
//  PHAsset+x.m
//  XPhoto
//
//  Created by baboy on 2019/2/22.
//  Copyright © 2019 baboy. All rights reserved.
//

#import "PHAsset+x.h"
#import <UIKit/UIKit.h>

@implementation PHAsset(x)
+ (PHFetchResult<PHAsset *> *)fetchAllAssetsWithMediaType:(PHAssetMediaType)mediaType soryByCreationDateAsc:(BOOL)isAsc{
    PHFetchOptions *options = [[PHFetchOptions alloc] init];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0f) {
        options.includeAssetSourceTypes = PHAssetSourceTypeUserLibrary;
    }
    options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:isAsc]];
    options.includeAssetSourceTypes = PHAssetSourceTypeUserLibrary;
    if (mediaType == PHAssetMediaTypeUnknown) {
        return [PHAsset fetchAssetsWithOptions:options];
    }
    return  [PHAsset fetchAssetsWithMediaType:mediaType options:options];
}
-(CGSize)imageSize{
    CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
    CGFloat multiple = [UIScreen mainScreen].scale;
    CGFloat aspectRatio = self.pixelWidth / (CGFloat)self.pixelHeight;
    CGFloat pixelWidth = photoWidth * multiple;
    CGFloat pixelHeight = pixelWidth / aspectRatio;
    return  CGSizeMake(pixelWidth, pixelHeight);
}
-(void)loadHighQualityImageWithProgressHandler:(void(^)(double progress, NSError * error))progressHandler resultHandler:(void (^)(UIImage* result, NSDictionary * info))resultHandler{
    
    CGSize imageSize = [self imageSize];
    PHImageRequestOptions * options = [[PHImageRequestOptions alloc] init];
    //设置该模式，若本地无高清图会立即返回缩略图，需要从iCloud下载高清，会再次调用resultHandler返回下载后的高清图
    options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    options.resizeMode = PHImageRequestOptionsResizeModeFast;
    options.networkAccessAllowed = YES;
    options.progressHandler = ^(double progress, NSError *__nullable error, BOOL *stop, NSDictionary *__nullable info){
        if (progressHandler) {
            dispatch_async(dispatch_get_main_queue(), ^{
                progressHandler(progress,error);
            });
        }
    };
    
    [[PHCachingImageManager defaultManager] requestImageForAsset:self
                                                      targetSize:imageSize
                                                     contentMode:PHImageContentModeAspectFill
                                                         options:options
                                                   resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        //判断高清图
        //   BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
        if (result && resultHandler) {
            resultHandler(result,info);
        }
    }];
}

-(void)loadHighQualityImageSynchronousWithProgressHandler:(void(^)(double progress, NSError * error))progressHandler resultHandler:(void (^)(UIImage* result, NSDictionary * info))resultHandler{
    CGSize imageSize = [self imageSize];
    PHImageRequestOptions * options = [[PHImageRequestOptions alloc] init];
    //        options.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    options.resizeMode = PHImageRequestOptionsResizeModeExact;
    options.networkAccessAllowed = YES;
    //同步保证取出图片顺序和选择的相同，deliveryMode默认为PHImageRequestOptionsDeliveryModeHighQualityFormat
    options.synchronous = YES;
    
    options.progressHandler = ^(double progress, NSError *__nullable error, BOOL *stop, NSDictionary *__nullable info){
        dispatch_async(dispatch_get_main_queue(), ^{
            progressHandler(progress,error);
        });
    };
    
    [[PHCachingImageManager defaultManager] requestImageForAsset:self
                                                      targetSize:imageSize
                                                     contentMode:PHImageContentModeAspectFill
                                                         options:options
                                                   resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        //resultHandler默认在主线程，requestImageForAsset在子线程执行后resultHandler变为在子线程
        if (result && resultHandler) {
            //压缩图片，可用于上传
            resultHandler(result, info);
        }
    }];
}

-(void)loadLowQualityImageWithTargetSize:(CGSize)targetSize progressHandler:(void(^)(double progress, NSError * error))progressHandler resultHandler:(void (^)(UIImage* result, NSDictionary * info))resultHandler{
    
    
    [[PHCachingImageManager defaultManager] requestImageForAsset:self
                                                      targetSize:targetSize
                                                     contentMode:PHImageContentModeAspectFill
                                                         options:nil
                                                   resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                                                       //判断高清图
                                                       //   BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
                                                       if (result && resultHandler) {
                                                           resultHandler(result,info);
                                                       }
                                                   }];
}



- (void)videoURLAssetWithProgressHandler:(void(^)(double progress, NSError * error))progressHandler
                           resultHandler:(void(^)(AVURLAsset *urlAsset, NSError *error)) resultHandler;{
    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
    options.version = PHImageRequestOptionsVersionCurrent;
    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
    options.networkAccessAllowed = YES;
    options.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
        if (progressHandler) {
            progressHandler(progress, error);
        }
    };
    
    PHImageManager *manager = [PHImageManager defaultManager];
    [manager requestAVAssetForVideo:self options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        AVURLAsset *urlAsset = (AVURLAsset *)asset;
        resultHandler(urlAsset, nil);
    }];
}

+ (void)saveImageToPhotoLib:(UIImage *)image resultHandler:(void (^)(PHAsset * _Nonnull, NSError * _Nonnull))resultHandler{
    __block NSString *localIdentifier = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        //写入图片到相册
        PHAssetChangeRequest *req = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        //记录本地标识，等待完成后取到相册中的图片对象
        localIdentifier = req.placeholderForCreatedAsset.localIdentifier;
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        NSLog(@"success = %d, error = %@", success, error);
        //成功后取相册中的图片对象
        PHAsset *photoAsset = nil;
        if (success){
            PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
            if(result.count > 0){
                photoAsset = [result objectAtIndex:0];
            }
        }
        if(resultHandler){
            resultHandler(photoAsset, error);
        }
    }];

}
- (void)requestImageWithResultHandler:(void(^)(UIImage *image)) resultHandler{
    PHImageRequestOptions * options = [[PHImageRequestOptions alloc] init];
    //        options.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    options.resizeMode = PHImageRequestOptionsResizeModeExact;
    options.networkAccessAllowed = YES;
    //同步保证取出图片顺序和选择的相同，deliveryMode默认为PHImageRequestOptionsDeliveryModeHighQualityFormat
    options.synchronous = YES;
    [[PHImageManager defaultManager] requestImageDataForAsset:self
                                                      options:options
                                                resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
        if(imageData){
            UIImage *image  = [UIImage imageWithData:imageData];
            if (resultHandler) {
                resultHandler(image);
            }
        }
        
    }];
}
- (void)exportToFilePath:(NSString *)fp resultHandler:(void(^)(NSError *error)) resultHandler{
    [self videoURLAssetWithProgressHandler:^(double progress, NSError * _Nonnull error) {
        
    } resultHandler:^(AVURLAsset * _Nonnull urlAsset, NSError * _Nonnull error) {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:urlAsset presetName:AVAssetExportPresetHighestQuality];
                //  NSLog(resultPath);
                exportSession.outputURL = [NSURL URLWithString:fp];
                exportSession.outputFileType = AVFileTypeMPEG4;
                exportSession.shouldOptimizeForNetworkUse= YES;
                [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
                 {
                     switch (exportSession.status) {
                         case AVAssetExportSessionStatusCancelled:
                             DLOG(@"AVAssetExportSessionStatusCancelled");
                             break;
                         case AVAssetExportSessionStatusUnknown:
                             DLOG(@"AVAssetExportSessionStatusUnknown");
                             break;
                         case AVAssetExportSessionStatusWaiting:
                             DLOG(@"AVAssetExportSessionStatusWaiting");
                             break;
                         case AVAssetExportSessionStatusExporting:
                             DLOG(@"AVAssetExportSessionStatusExporting");
                             break;
                         case AVAssetExportSessionStatusCompleted:
                             DLOG(@"AVAssetExportSessionStatusCompleted");
                             if (resultHandler) {
                                 resultHandler(nil);
                             }
                             break;
                         case AVAssetExportSessionStatusFailed:
                             DLOG(@"AVAssetExportSessionStatusFailed");
                             if (resultHandler) {
                                 resultHandler(exportSession.error);
                             }
                             break;
                     }
                       
                 }];
    }];
}
+ (void)saveVideoToPhotoLib:(NSURL *)videoURL resultHandler:(void(^)(PHAsset *asset, NSError *error)) resultHandler{
    
    __block NSString *localIdentifier = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *req = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoURL];
        localIdentifier = req.placeholderForCreatedAsset.localIdentifier;
        

    }
                                      completionHandler:^(BOOL success, NSError * _Nullable error) {
        NSLog(@"success = %d, error = %@", success, error);
        //成功后取相册中的图片对象
        PHAsset *photoAsset = nil;
        if (success){
            PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
            if(result.count > 0){
                photoAsset = [result objectAtIndex:0];
            }
        }
        if(resultHandler){
            resultHandler(photoAsset, error);
        }
    }];
}

@end
